using dotnet_ef_admin.Src.Models;
using dotnet_ef_admin.Src.Utilities;

using Microsoft.EntityFrameworkCore;

namespace dotnet_ef_admin.Src.Services;

public class DeptService(DbCtx _context) : IDeptService {
    /// <summary>
    ///     异步获取所有符合条件的部门列表。
    /// </summary>
    /// <param name="request">查询请求。</param>
    /// <returns>包含所有符合条件的部门列表。</returns>
    public async Task<IEnumerable<DeptList>> GetDeptsAsync(FindAllRequest request) {
        // 获取所有符合条件的部门
        var depts = await _context.Depts
            .Where(dept => string.IsNullOrEmpty(request.Keywords) || dept.Name.Contains(request.Keywords))
            .Where(dept => !request.Status.HasValue || dept.Status == request.Status)
            .ToListAsync();

        // 将部门转换为 DeptList 对象
        var deptList = depts.Select(dept => new DeptList {
            Id = dept.Id,
            Name = dept.Name,
            ParentId = dept.ParentId,
            CreateTime = dept.CreateTime,
            UpdateTime = dept.UpdateTime,
            Sort = dept.Sort,
            Status = dept.Status,
            Children = [] // 初始化 Children 列表
        }).ToList();

        // 如果有查询条件，直接返回扁平列表
        if (!string.IsNullOrEmpty(request.Keywords) || request.Status.HasValue) {
            return deptList;
        }

        // 构建树形结构
        foreach (var dept in deptList) {
            // 找到当前部门的父部门
            if (dept.ParentId != 0) {
                // 找到父部门并将当前部门添加到父部门的 Children 列表中
                var parentDept = deptList.FirstOrDefault(d => d.Id == dept.ParentId);
                parentDept?.Children.Add(dept);
            }
        }

        // 只返回顶级部门（ParentId 为 0 的部门）
        return deptList.Where(dept => dept.ParentId == 0).ToList();
    }

    /// <summary>
    ///     根据部门ID获取部门信息。
    /// </summary>
    /// <param name="id">部门ID。</param>
    /// <returns>返回与ID匹配的部门，如果没有找到则返回null。</returns>
    public async Task<Dept?> GetDeptByIdAsync(int id) {
        return await _context.Depts.FindAsync(id);
    }

    /// <summary>
    ///     创建部门并保存到数据库。
    /// </summary>
    /// <param name="dept">要创建的部门对象。</param>
    /// <returns>创建的部门。</returns>
    public async Task<Dept> CreateDeptAsync(Dept dept) {

        // 检查数据库中是否已有同名的部门
        var existingDept = await _context.Depts.AnyAsync(d => d.Name == dept.Name);

        if (existingDept) {
            throw new InvalidOperationException("部门已存在");
        }

        _context.Depts.Update(dept);
        await _context.SaveChangesAsync();
        return dept;
    }

    /// <summary>
    ///     更新数据库中的现有部门。
    /// </summary>
    /// <param name="dept">要更新的部门对象。</param>
    /// <returns>更新后的部门。</returns>
    public async Task<Dept> UpdateDeptAsync(Dept dept) {
        dept.UpdateTime = DateTimeUtils.GetCurrentTimeString();
        _context.Depts.Update(dept);
        await _context.SaveChangesAsync();
        return dept;
    }

    /// <summary>
    ///     从数据库中删除部门。
    /// </summary>
    /// <param name="id">要删除的部门的ID。</param>
    public async Task DeleteDeptAsync(int id) {
        var dept = await _context.Depts.FindAsync(id);
        if (dept != null) {
            _context.Depts.Remove(dept);
            await _context.SaveChangesAsync();
        }
    }

    /// <summary>
    /// 获取部门选项列表。
    /// </summary>
    /// <returns>包含部门选项的列表。</returns>
    public async Task<List<TransformedItem>> GetDeptOptionsAsync() {
        // 获取所有部门
        var depts = await _context.Depts.ToListAsync();

        // 将部门转换为选项列表
        // 使用 Utils.TransformToOption 方法将部门列表转换为选项列表
        var deptOptions = Utils.TransformToOption(depts.Cast<object>().ToList());

        // 返回转换后的选项列表
        return deptOptions;
    }
}
